package com.ainiyar.springweb.config.security;

import com.ainiyar.springweb.config.security.filter.AuthCheckFilter;
import com.ainiyar.springweb.config.security.handler.AuthenticationHandler;
import com.ainiyar.springweb.config.security.handler.CustomAccessHandler;
import com.ainiyar.springweb.config.security.handler.LoginFailureHandler;
import com.ainiyar.springweb.config.security.handler.LoginSuccessHandler;
import com.ainiyar.springweb.config.security.service.CustomerAdminDetailsService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


/**************************************
 * File Name : SecurityConfig
 * Created with : IntelliJ IDEA.
 * Author : 艾尼亚尔·毛拉吾提
 * QQ : 524155792  WeChat : ainiyar0124
 * Created Time : 2024/2/4  16:34
 * Desc :Security配置类
 ***************************************/
@Configuration
@EnableMethodSecurity(prePostEnabled = true)//开启方法级别的权限验证
public class SecurityConfig {
    @Resource
    private AuthenticationHandler anonymousAuthenticationHandler;
    @Resource
    private AuthCheckFilter authCheckFilter;
    @Resource
    private CustomerAdminDetailsService customerAdminDetailsService;
    @Resource
    private CustomAccessHandler customAccessHandler;
    @Resource
    private LoginSuccessHandler loginSuccessHandler;
    @Resource
    private LoginFailureHandler loginFailureHandler;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.addFilterBefore(authCheckFilter, UsernamePasswordAuthenticationFilter.class);
        http.csrf(csrf -> csrf.disable())
                .exceptionHandling(exceptions -> {
                    exceptions.authenticationEntryPoint(anonymousAuthenticationHandler);
                    exceptions.accessDeniedHandler(customAccessHandler);
                })
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests((authorize) -> authorize
                        .requestMatchers("/admin/captcha").permitAll()
                        .requestMatchers("/admin/do_login").permitAll()
                        .requestMatchers("/admin/get_config").permitAll()//配置
                        .requestMatchers("/applet/**").permitAll()
                        .requestMatchers("/admin/file/**").anonymous()//后台访问静态文件
                        .anyRequest().authenticated()
                ).formLogin(form -> {
                    form.loginProcessingUrl("/admin/do_login")
                            .successHandler(loginSuccessHandler)
                            .failureHandler(loginFailureHandler)
                            .permitAll();
                })
                .userDetailsService(customerAdminDetailsService);
        return http.build();
    }

    @Resource
    private AuthenticationConfiguration authenticationConfiguration;

    @Bean
    AuthenticationManager authenticationManager() throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
}

